package com.alien.admin.context.task.handle.impl;

import com.alien.admin.context.task.DeployStatusTimeline;
import com.alien.admin.context.task.handle.DeployJobHandler;
import com.alien.admin.context.task.TaskQueue;

import com.alien.admin.modules.basic.service.K8sService;
import com.alien.admin.modules.deploy.domain.DeployRec;
import com.alien.admin.modules.deploy.domain.DpK8sInstance;

import com.alien.admin.modules.deploy.repository.DeployRecRepository;
import com.alien.admin.modules.deploy.repository.DpK8sInstanceRepository;
import com.alien.admin.modules.deploy.repository.DpServerConfigRepository;
import com.alien.admin.modules.deploy.repository.DpServerRepository;
import com.alien.admin.utils.DeployConstant;

import com.alien.admin.utils.ValidationUtil;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * @Description:
 * @Author: zsy
 * @Date: 2021/10/28 10:45
 */
@Slf4j
@Data
@Component
public class K8SHealthCheckHandler implements DeployJobHandler {
    @Autowired
    private DeployRecRepository deployRecRepository;
    @Autowired
    private K8sService k8sService;
    @Autowired
    private DpServerConfigRepository dpServerConfigRepository;
    @Autowired
    private DpServerRepository dpServerRepository;
    @Autowired
    private DpK8sInstanceRepository dpK8sInstanceRepository;
    @Autowired
    private TaskQueue taskQueue;
    @Autowired
    private DeployStatusTimeline deployStatusTimeline;

    private DpK8sInstance initDpK8sInstance(DeployRec deployRec) {
        Integer k8sInstanceId = deployRec.getK8SInstanceId();
        DpK8sInstance k8sInstance = dpK8sInstanceRepository.findById(k8sInstanceId).orElseGet(DpK8sInstance::new);
        ValidationUtil.isNull(k8sInstance.getId(), "DpK8sInstance", "id", k8sInstance.getId());

        return k8sInstance;
    }

    @Override
    public void process(DeployRec deployRec) {
        try {
            DpK8sInstance k8sInstance = initDpK8sInstance(deployRec);

            accessLog(k8sInstance, deployRec);

            // 提取构建结果和日志内容
            String podName = deployRec.getProjectName();
            String namespace = deployRec.getNameSpace();
            boolean ok = k8sService.healthCheck(k8sInstance, namespace, podName);
            // 部署流程状态
            if (ok) {
                save(DeployConstant.DEPLOY_STATUS_SUCCESS, deployRec);
                return;
            }

            // 保存数据库
            save(DeployConstant.DEPLOY_STATUS_RUNNING, deployRec);
        } catch (Exception e) {
            log.error("获取k8s日志！", e);
        }

        // 未结束，且未超时，才能继续入队
        Boolean alive = deployStatusTimeline.isAlive(deployRec.getId());
        if(alive) {
            if(!taskQueue.isCancelTask(deployRec.getId())) {
                taskQueue.putTaskToQueue(deployRec.getId());
            }
        } else {
            // 超时，部署流程失败
            save(DeployConstant.DEPLOY_STATUS_FAILED, deployRec);
        }
    }

    private void accessLog(DpK8sInstance k8sInstance, DeployRec deployRec) {
        try {
            String podName = deployRec.getProjectName();
            String namespace = deployRec.getNameSpace();
            String logContent = k8sService.getDeploymentLog(k8sInstance, namespace, podName);
            deployRec.setDeployLog(logContent);
        } catch (Exception e) {
            e.printStackTrace();
            // 获取日志失败，不影响部署
        }
    }

    private void save(Integer deployStatus, DeployRec deployRec) {
        if(!taskQueue.isCancelTask(deployRec.getId())) {
            deployRec.setDeployStatus(deployStatus);
            deployRecRepository.save(deployRec);
        }
    }
}
